package com.wdl.modules.myhouse.controller.sys;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wdl.modules.myhouse.common.Code;
import com.wdl.modules.myhouse.common.Result;
import com.wdl.modules.myhouse.dto.SysMenuDTO;
import com.wdl.modules.myhouse.entity.sys.SysMenuEntity;
import com.wdl.modules.myhouse.entity.sys.SysRoleEntity;
import com.wdl.modules.myhouse.security.entity.UserInfo;
import com.wdl.modules.myhouse.service.SysMenuRoleService;
import com.wdl.modules.myhouse.service.SysMenuService;
import com.wdl.modules.myhouse.utils.util.PageUtil;
import com.wdl.modules.myhouse.vo.MenuNodeSaveVO;
import com.wdl.modules.myhouse.vo.MenuNodeVO;
import com.wdl.modules.myhouse.vo.PageVO;
import com.wdl.modules.myhouse.vo.SysMenuVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 菜单表
 *
 * @author lucain sunlightcs@gmail.com
 * @since 1.0.0 2022-09-11
 */
@RestController
@RequestMapping("/sysMenu")
@Api(tags = "菜单表")
@Slf4j
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysMenuRoleService menuRoleService;

    @ApiOperation("获取节点树")
    @GetMapping("/nodeTree")
    public Result<List<MenuNodeVO>> getNodeTree() {
        return new Result<List<MenuNodeVO>>().ok().setData(sysMenuService.buildMenuTree());
    }


    @PutMapping("/{id}")
    @ApiOperation("按照id更新元素")
    public Result update(@PathVariable("id") Integer id, @RequestBody MenuNodeSaveVO vo) {
        SysMenuEntity entity = new SysMenuEntity();
        try {
            entity.setParentId(vo.getId()[vo.getId().length - 1]);
        } catch (NullPointerException e) {
            log.info("新增父节点: {}", vo.getMenuName());
            entity.setParentId(null);
        } catch (ArrayIndexOutOfBoundsException e) {
            entity.setParentId(null);
            log.info("新增父节点: {}", vo.getMenuName());
        }
        BeanUtils.copyProperties(vo, entity);
        entity.setId(id);
        if (sysMenuService.updateById(entity)){
            return new Result<>().ok();
        }
        return new Result<>().error();
    }

    @DeleteMapping("/{id}")
    @ApiOperation("按照id删除元素")
    public Result<Boolean> del(@PathVariable("id") Integer id) {
        if (sysMenuService.removeById(id)) {
            return new Result<Boolean>().ok();
        }
        return new Result<Boolean>().error();
    }

    @GetMapping("/allMenu/page")
    @ApiOperation("分页查找角色")
    public Result<IPage<SysMenuEntity>> getRoleByPage(PageVO page) {
        log.info("角色分页对象", page.toString());
        return new Result<IPage<SysMenuEntity>>().ok().setData(sysMenuService.getMenuByPage(PageUtil.pageVo2MyPage(page)));
    }


    @PostMapping("/save")
    public Result save(@RequestBody MenuNodeSaveVO vo) {
        SysMenuEntity menuEntity = new SysMenuEntity();
        BeanUtils.copyProperties(vo, menuEntity);
        try {
            menuEntity.setParentId(vo.getId()[vo.getId().length - 1]);
        } catch (NullPointerException e) {
            log.info("新增父节点: {}", vo.getMenuName());
            menuEntity.setParentId(null);
        } catch (ArrayIndexOutOfBoundsException e) {
            menuEntity.setParentId(null);
            log.info("新增父节点: {}", vo.getMenuName());
        }
        boolean save = sysMenuService.save(menuEntity);
        if (save) {
            return new Result().ok();
        } else {
            return new Result().error(Code.COMMON_ERROR.getCode(), "菜单信息保存失败");
        }

    }


    @GetMapping("/allMenu")
    public Result<List<SysMenuVO>> getAllMenu() {
        UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<SysRoleEntity> roles = userInfo.getRoles();
        List<Integer> roleIds = roles.stream().map(role -> role.getSid()).collect(Collectors.toList());
        List<SysMenuEntity> menus = menuRoleService.getMenusByRoleIds(roleIds);
        Map<Integer, SysMenuEntity> id2Entity = menus.stream().collect(Collectors.toMap(SysMenuEntity::getId, en -> en));
        List<SysMenuVO> menuVos = menus.stream().map(en -> {
            SysMenuVO menuVO = new SysMenuVO();
            BeanUtils.copyProperties(en, menuVO);
            try {
                menuVO.setParentNodeName(id2Entity.get(en.getParentId()).getMenuName());
            } catch (NullPointerException e) {
                menuVO.setParentNodeName("");
            }
            return menuVO;
        }).collect(Collectors.toList());
        return new Result<List<SysMenuVO>>().ok().setData(menuVos);
    }

    @GetMapping("/searchByKey/{key}")
    public Result<List<SysMenuVO>> searchByKey(@PathVariable("key") String key) {
        UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<SysRoleEntity> roles = userInfo.getRoles();
        List<Integer> roleIds = roles.stream().map(role -> role.getSid()).collect(Collectors.toList());
        List<SysMenuEntity> menus = menuRoleService.getMenusByRoleIds(roleIds);
        Map<Integer, SysMenuEntity> id2Entity = menus.stream().collect(Collectors.toMap(SysMenuEntity::getId, en -> en));
        List<SysMenuVO> menuVos = menus.stream().map(en -> {
            SysMenuVO menuVO = new SysMenuVO();
            BeanUtils.copyProperties(en, menuVO);
            try {
                menuVO.setParentNodeName(id2Entity.get(en.getParentId()).getMenuName());
            } catch (NullPointerException e) {
                menuVO.setParentNodeName("");
            }
            return menuVO;
        }).filter(vo ->
                vo.getMenuName().contains(key) || vo.getParentNodeName().contains(key)
        ).collect(Collectors.toList());

        return new Result<List<SysMenuVO>>().ok().setData(menuVos);
    }


}